package cc.rboot._core.util;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class ListUtils {

    public static <K, V> Map<K, V> toMap(List<V> list, Function<V, K> function) {
        return list.stream().collect(Collectors.toMap(function, Function.identity()));
    }

    public static <K, V> Map<K, V> toDistinctMap(List<V> list, Function<V, K> function) {
        return list.stream().collect(Collectors.toMap(function, item -> item, (item1, item2) -> item1));
    }

    public static <T, R> List<R> deepList(List<T> list, Function<T, R> mapper) {
        return list.stream().map(mapper).collect(Collectors.toList());
    }

    public static <T, R> List<R> deepDistinctList(List<T> list, Function<T, R> mapper) {
        return list.stream().map(mapper).distinct().collect(Collectors.toList());
    }

    public static <T, R> List<R> deepDistinctNonNullList(List<T> list, Function<T, R> mapper) {
        return list.stream().map(mapper).distinct().filter(Objects::nonNull).collect(Collectors.toList());
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}
